﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpModelInterface.h"
#include "IEventArgs.h"
#include "ElementId.h"
#include "IGroup.h"

namespace gcmp
{
    class IDocument;

    /// \brief 成组事件类型
    enum class GroupEventType : int32_t
    {
        PreCreate = 1,              ///< 创建组类型或组之前，发送此消息
                                    ///< 当sourceElementId无效时，表示创建组类型
                                    ///< 当sourceElementId有效时，Id为组类型Id，表示由组类型创建组
        PostCreate = 2,             ///< 创建组类型或组之后，发送此消息
                                    ///< sourceElementId始终为GroupTypeId，targetElementId始终为GroupId

        PreSync = 10,               ///< 已废弃
        PostSync = 11,              ///< 已废弃

        PreSyncAdd = 12,            ///< 同步添加前
        PostSyncAdd = 13,           ///< 同步添加后
        PreSyncChange = 14,         ///< 同步修改前
        PostSyncChange = 15,        ///< 同步修改后
        PreSyncDelete = 16,         ///< 同步删除前
        PostSyncDelete = 17,        ///< 同步删除后
        PreSyncRemove = 18,         ///< 同步移除前
        PostSyncRemove = 19,        ///< 同步移除后
        
        PostSyncCopy = 20,          ///< 已废弃

        PreGroupTypeUpdate = 21,    ///< 对GroupType进行同步前，发送此消息
                                    ///< sourceElementId为修改的GroupId，targetElementId为GroupTypeId
        PostGroupTypeUpdate = 22,   ///< 对GroupType进行同步后，发送此消息
                                    ///< sourceElementId为修改的GroupId，targetElementId为GroupTypeId
                                    ///< syncDatas包含同步过程中的所有事件
        PreGroupUpdate = 23,        ///< 对Group进行同步前，发送此消息
                                    ///< sourceElementId为GroupTypeId，targetElementId为修改的GroupTypeId
        PostGroupUpdate = 24,       ///< 对Group进行同步后，发送此消息
                                    ///< sourceElementId为GroupTypeId，targetElementId为修改的GroupTypeId
                                    ///< syncDatas包含同步过程中的所有事件

        PreSyncRestore = 25,        ///< 同步恢复前
        PostSyncRestore = 26        ///< 同步恢复后
    };


    /// \brief 组同步事件数据的结构体
    struct GCMP_MODEL_INTERFACE_EXPORT GroupSyncData
    {
        /// \brief 构造GroupSyncData
        ///
        /// \param editType 操作类型
        /// \param sourceId 源编辑对象
        /// \param targetId 目标编辑对象
        GroupSyncData(GroupEditType editType, const ElementId& sourceId, const ElementId& targetId);

        GroupEditType EditType;     ///< 操作类型
        ElementId SourceElementId;  ///< 源编辑对象
        ElementId TargetElementId;  ///< 目标编辑对象
    };


    /// \brief  成组事件参数
    ///
    class GCMP_MODEL_INTERFACE_EXPORT IGroupEventArgs : public IEventArgs
    {
        DEFINE_CAST_DERIVED(gcmp::IGroupEventArgs, gcmp::IEventArgs)
    public:
        /// \brief 获取拷贝事件类型
        /// \return 拷贝事件类型
        virtual GroupEventType GetType() const = 0;

        /// \brief 获取拷贝事件对应的文档
        /// \return 文档指针
        virtual IDocument* GetDocument() = 0;

        /// \brief 获取事件中源对象的Id
        /// \return 源对象的Id
        virtual ElementId GetSourceElementId() const = 0;

        /// \brief 获取事件中目标对象的Id
        /// \return 目标对象的Id
        virtual ElementId GetTargetElementId() const = 0;
        
        /// \brief 获取同步数据
        /// \return 返回同步数据的vector
        /// \note 只在PostGroupTypeUpdate和PostGroupUpdate时调用该接口有效，其他事件该接口获取数据为空
        virtual const std::vector<GroupSyncData>& GetSyncDatas() const = 0;

        /// \brief 判断同步发生的时机;
        /// \return true表示是从GroupType到Group的同步，false表示Group到GroupType的同步
        virtual bool IsGroupTypeToGroupSync() const = 0;

        /// \brief 获取同步时GroupType的ID
        /// \return GroupType的ID
        virtual ElementId GetGroupTypeId() const = 0;

        /// \brief 获取同步时Group的ID
        /// \return Group的ID
        virtual ElementId GetGroupId() const = 0;

        /// \brief 获取拷贝事件中对应的元素的ElementId
        /// \return 拷贝元素的ElementId的集合
        GCMP_DEPRECATED_API(2021/09/01) virtual const std::vector<ElementId>& GetSourceElementIds() const = 0;

        /// \brief 获取拷贝事件中新拷贝的元素的ElementId
        /// \return 新拷贝元素的ElementId的集合
        GCMP_DEPRECATED_API(2021/09/01) virtual const std::vector<ElementId>& GetTargetElementIds() const = 0;

        /// \brief 所有拷贝了的从源Element到目标Element的对应表
        /// \return 返回所有拷贝了的从源Element到目标Element的对应表
        GCMP_DEPRECATED_API(2021/09/01) virtual const std::map<ElementId, ElementId>& GetAllSourceToTargetIdsMap() const = 0;
    };
}
